package service

import (
	"encoding/json"
	"pq/models"
	"github.com/astaxie/beego/orm"
	"pq/repository"
)

type TestCategoryService struct{

}
func (tc TestCategoryService) GetCategoryById(id int) (models.PqTestCategory,error){
	repo := repository.TestCategoryRepository{}
	return repo.GetById(id)
}
func (tc TestCategoryService) GetSettingPointTree(pointSetting string)[]orm.Params{
	var o map[string]string
	var ptnodes = map[string] []orm.Params{}
	var chnodes = map[string] orm.Params{}
	var finals  []orm.Params
	_ = json.Unmarshal([]byte(pointSetting), &o)
	//1.get whole the point tree
	cate := &models.PqTestPointCategory{}
	cates,_ := cate.ListAll([]interface{}{-1},"root")
	for _,c := range cates {
		ptnodes[c["pid"].(string)] = append(ptnodes[c["pid"].(string)],c)
		chnodes[c["id"].(string)] = c
	}
	//2.keep related nodes and their children
	for p,pv := range o{
		if pv == ""{
			continue
		}
		if n,ok:=chnodes[p];ok{
			finals = append(finals, n)
			//a.get all childrens
			finals = tc.getAllChilds(p,ptnodes,finals)
			//b.get all parent
			finals = tc.getAllParents(p,chnodes,finals)
			//c.remove parents,reduce useless operating
			for _,f := range finals{
				delete(chnodes,f["id"].(string))
			}
			delete(chnodes,p)
		}
	}
	for k,_ := range finals {
		finals[k]["finish_rate"] = "30/290"
		finals[k]["finish_star"] = "4"
	}
	return finals
}

func (tc TestCategoryService) getAllChilds(id string,treeRs map[string][]orm.Params,keep []orm.Params) []orm.Params{
	if _,ok := treeRs[id];ok {
		for _, child := range treeRs[id] {
			//for _,child := range childs {
			keep = append(keep, child)
			if _,next := treeRs[child["id"].(string)];next{
				tc.getAllChilds(child["id"].(string),treeRs,keep)
			}
		}
	}
	return keep
}

func (tc TestCategoryService) getAllParents(id string,treeRs map[string] orm.Params,keep []orm.Params) []orm.Params{
	if node,ok := treeRs[id];ok{
		if parent,pok := treeRs[node["pid"].(string)];pok{
			for pok{
				keep = append(keep,parent)
				parent,pok = treeRs[parent["pid"].(string)]
			}
		}
	}
	return keep
}